﻿<template>
  <!-- 设计稿 1920×1080，根据窗口状态动态切换模式 -->
  <v-scale-screen width="1920" height="1080" :boxStyle="{ background: '#131615' }">
    <div class="machine-container" :class="{
      'machine-container-detail': viewMode === 'detail' || viewMode === 'streaming',
      'machine-container-decision': currentScene.value === 'decision'
    }">
      <!-- 左上角时间显示 -->
      <TimeDisplay />

      <!-- 主要内容区域 -->
      <div class="content-area">
        <!-- 顶部搜索和场景切换区域 -->
        <div class="top-bar">
          <!-- 左侧：搜索栏和日期选择器（仅在列表视图显示） -->
          <div v-if="viewMode === 'list'" class="search-section">
            <!-- 搜索框 -->
            <div class="search-box">
              <input v-model="query.inputKeyword" type="text" placeholder="请输入编号、名称" class="search-input" />
            </div>

            <!-- 日期选择器 -->
            <div class="date-picker">
              <el-date-picker v-model="query.inputDate" type="date" value-format="YYYY-MM-DD" placeholder="选择发布时闶间"
                class="date-input" />
            </div>

            <!-- 查询按钮 -->
            <button class="query-btn" @click="handleQuery">查询</button>

            <!-- 重置按钮 -->
            <button class="reset-btn" @click="handleReset">重置</button>
          </div>

          <!-- 右侧：场景切换下拉菜单（全局右上角） -->
          <div class="scene-selector"
            :class="{ 'scene-selector-detail': viewMode === 'detail' || viewMode === 'streaming' }">
            <img :src="dropdownOpen ? upIcon : downIcon" alt="展开" class="dropdown-icon" @click="toggleDropdown" />

            <!-- 下拉菜单 -->
            <div v-if="dropdownOpen" class="dropdown-menu">
              <div v-for="scene in scenes" :key="scene.value" class="menu-item"
                :class="{ active: currentScene.value === scene.value }" @click="selectScene(scene)">
                <img :src="currentScene.value === scene.value ? scene.selectedIcon : scene.icon" alt=""
                  class="menu-icon" />
                <span>{{ scene.label }}</span>
              </div>
            </div>
          </div>
        </div>

        <!-- 历史记录列表视图 -->
        <div v-if="viewMode === 'list'" class="history-list">
          <!-- 加载遮罩层 -->
          <div v-if="isLoading" class="loading-overlay">
            <img :src="loadingGif" alt="加载中" class="loading-gif" />
            <p class="loading-text">正在加载数据...</p>
          </div>

          <!-- 空数据状态 -->
          <div v-if="!isLoading && totalCount === 0" class="empty-state">
            <div class="empty-icon">
              <img :src="nullImage" alt="暂无数据" />
            </div>
          </div>

          <!-- 卡片网格 -->
          <div v-if="!isLoading && totalCount > 0" class="card-grid">
            <div v-for="item in historyList" :key="item.id" class="history-card"
              :class="{ selected: selectedCardId === item.id }" @click="viewDetail(item)"
              @mouseenter="hoveredCardId = item.id" @mouseleave="hoveredCardId = null">
              <div class="card-title">{{ item.title }}</div>
              <div class="card-content">
                <div class="info-row">
                  <span class="info-label"><span class="dot"></span>计划名称：</span>
                  <span class="info-value">{{ item.planName }}</span>
                </div>
                <div class="info-row">
                  <span class="info-label"><span class="dot"></span>发布时间：</span>
                  <span class="info-value">{{ item.publishTime }}</span>
                </div>
                <div class="info-row">
                  <span class="info-label"><span class="dot"></span>有效期限：</span>
                  <span class="info-value">{{ item.validPeriod }}</span>
                </div>
                <div class="info-row">
                  <span class="info-label"><span class="dot"></span>创建时间：</span>
                  <span class="info-value">{{ item.createTime }}</span>
                </div>
              </div>
              <button class="view-btn">查看 <img
                  :src="(selectedCardId === item.id || hoveredCardId === item.id) ? zheBlackIcon : zheIcon" alt=">"
                  class="btn-icon" /></button>
            </div>
          </div>

          <!-- Element Plus 分页组件 -->
          <div v-if="totalCount > 0" class="pagination-wrapper">
            <el-pagination v-model:current-page="currentPage" :page-size="pageSize" :total="totalCount"
              layout="total, prev, pager, next, jumper" @current-change="handlePageChange" />
          </div>
        </div>

        <!-- 历史记录详情视图 -->
        <div v-if="viewMode === 'detail'" class="detail-view">
          <MachineDetail :history-data="selectedDetail" :streaming-markdown="''" :card-info="selectedCardInfo" />
        </div>

        <!-- 动态筹划视图（SSE场景） -->
        <div v-if="viewMode === 'streaming'" class="streaming-view">
          <MachineDetail :history-data="historyData" :streaming-markdown="streamingMarkdown"
            :card-info="selectedCardInfo" :is-gantt-loading="isGanttLoading" />
        </div>

        <!-- 决策思维链视图 -->
        <div v-if="viewMode === 'decision'" class="decision-view">
          <DecisionChain />
        </div>
      </div>
    </div>
  </v-scale-screen>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
// 引入 v-scale-screen 组件
import VScaleScreen from 'v-scale-screen'
// 引入时间显示组件
import TimeDisplay from '../subcomponents/Common/TimeDisplay.vue'
import { getHistoryCardList, getHistoryCardById } from '../api'
// 引入 MachineDetail 子组件
import MachineDetail from '../subcomponents/Machine/MachineDetail.vue'
// 引入 DecisionChain 子组件
import DecisionChain from '../subcomponents/Machine/DecisionChain.vue'
// 引入样式文件
import '../style/Matchine.css'
import '../style/Element.css'
// 引入图片资源
import nullImage from '../assets/Common/state-empty.png'
import downIcon from '../assets/Machine/icon-arrow-down.png'
import upIcon from '../assets/Machine/icon-arrow-up.png'
import timeSelectIcon from '../assets/Machine/icon-time-active.png'
import timeNoIcon from '../assets/Machine/icon-time-inactive.png'
import modelSelectIcon from '../assets/Machine/icon-model-active.png'
import modelNoIcon from '../assets/Machine/icon-model-inactive.png'
import echartsSelectIcon from '../assets/Machine/icon-chart-active.png'
import echartsNoIcon from '../assets/Machine/icon-chart-inactive.png'
import zheIcon from '../assets/Machine/icon-fold.png'
import zheBlackIcon from '../assets/Machine/icon-fold-black.png'
import loadingGif from '../assets/Common/loading-spinner.gif'

/**
 * 视图模式定义
 * - list: 历史记录列表模式，默认显示
 * - detail: 历史记录详情模式，点击列表项后进入
 * - streaming: 动态筹划模式，接收SSE流式数据时自动切换
 * - decision: 决策思维链模式，通过顶部下拉菜单手动切换
 */
const viewMode = ref<'list' | 'detail' | 'streaming' | 'decision'>('list')

// ==================== 响应式状态变量 ====================

/** 存储历史记录数据（用于streaming模式下的实时数据展示） */
const historyData = ref<any>(null)
/** 当前选中的详情数据（用于detail模式下的静态展示） */
const selectedDetail = ref<any>(null)
/** 当前选中的卡片ID */
const selectedCardId = ref<number | null>(null)
/** 当前鼠标悬停的卡片ID */
const hoveredCardId = ref<number | null>(null)
/** 当前选中卡片的基本信息（标题、时间等） */
const selectedCardInfo = ref<any>(null)
/** SSE场景下的卡片信息独立存储（避免与历史记录混淆） */
const sseCardInfo = ref<any>(null)

/**
 * 流式渲染：存储实时接收的 Markdown 内容
 * 主要用于思维导图（markmap）的逐字显示效果
 */
const streamingMarkdown = ref<string>('')

/**
 * Gantt智能体加载状态
 * 用于在gantt数据传输时显示加载遮罩
 */
const isGanttLoading = ref<boolean>(false)

// ==================== 搜索和筛选 ====================

/** 查询参数对象 */
const query = ref({
  inputKeyword: '', // 搜索关键词
  inputDate: '',    // 筛选日期
  pageNum: 1,       // 当前页码
  pageSize: 12      // 每页数量
})

/** 历史记录列表数据源 */
const historyList = ref<any[]>([])
/** 当前页码 */
const currentPage = ref<number>(1)
/** 每页显示条数 */
const pageSize = ref<number>(12)
/** 列表加载状态 */
const isLoading = ref<boolean>(false)
/** 数据总条数 */
const totalCount = ref<number>(0)

// 查询和重置功能
const handleQuery = () => {
  // 显示加载遮罩
  isLoading.value = true

  // 调用 API 获取历史记录列表
  const params = {
    keyword: query.value.inputKeyword,
    date: query.value.inputDate,
    page: 1,
    pageSize: query.value.pageSize
  }
  console.log('查询参数:', params)
  // getHistoryCardList(params)
  //   .then((res: any) => {
  let res = {
    list: [
      {
        id: 1,
        title: '计划A',
        planName: '东部',
        publishTime: '2025-11-15 09:30',
        validPeriod: '2025-11-15 至 2025-11-20',
        createTime: '2025-11-14 18:00',
      },
      {
        id: 2,
        title: '计划B',
        planName: '北部',
        publishTime: '2025-11-16 10:00',
        validPeriod: '2025-11-16 至 2025-11-22',
        createTime: '2025-11-15 20:30',

      },
      {
        id: 3,
        title: '联合计划C',
        planName: '陆海',
        publishTime: '2025-11-17 08:00',
        validPeriod: '2025-11-17 至 2025-11-25',
        createTime: '2025-11-16 14:45',

      },
      {
        id: 4,
        title: '计划D',
        planName: '后配送',
        publishTime: '2025-11-18 07:30',
        validPeriod: '2025-11-18 至 2025-11-23',
        createTime: '2025-11-17 16:20',

      },
      {
        id: 5,
        title: '搜救划E',
        planName: '紧急救',
        publishTime: '2025-11-19 06:00',
        validPeriod: '2025-11-19 至 2025-11-21',
        createTime: '2025-11-18 22:10',

      },
      {
        id: 6,
        title: '察划F',
        planName: '目侦察',
        publishTime: '2025-11-20 11:00',
        validPeriod: '2025-11-20 至 2025-11-26',
        createTime: '2025-11-19 19:40',

      },
      {
        id: 7,
        title: '训练计划G',
        planName: '新练',
        publishTime: '2025-11-21 14:30',
        validPeriod: '2025-11-21 至 2025-12-01',
        createTime: '2025-11-20 10:15',

      },
      {
        id: 8,
        title: '维划H',
        planName: '装定',
        publishTime: '2025-11-22 09:00',
        validPeriod: '2025-11-22 至 2025-11-28',
        createTime: '2025-11-21 15:30',

      },
      {
        id: 8,
        title: '维计划H',
        planName: '装修',
        publishTime: '2025-11-22 09:00',
        validPeriod: '2025-11-22 至 2025-11-28',
        createTime: '2025-11-21 15:30',

      },
      {
        id: 8,
        title: '维护计划H',
        planName: '装备修',
        publishTime: '2025-11-22 09:00',
        validPeriod: '2025-11-22 至 2025-11-28',
        createTime: '2025-11-21 15:30',

      },
      {
        id: 8,
        title: '维护划H',
        planName: '装检修',
        publishTime: '2025-11-22 09:00',
        validPeriod: '2025-11-22 至 2025-11-28',
        createTime: '2025-11-21 15:30',

      },
      {
        id: 8,
        title: '维护保H',
        planName: '期检修',
        publishTime: '2025-11-22 09:00',
        validPeriod: '2025-11-22 至 2025-11-28',
        createTime: '2025-11-21 15:30',

      },


    ], total: 12
  }
  console.log('查询结果:', res)

  // 更新历史记录列表
  if (res && res.list) {
    historyList.value = res.list || []
    totalCount.value = res.total || 0
  }

  // 重置到第一页
  query.value.pageNum = 1
  currentPage.value = 1

  console.log('执行查询:', query.value)

  // 隐藏加载遮罩
  isLoading.value = false
  // })
  // .catch((error: any) => {
  //   console.error('查询失败:', error)
  // })
  // .finally(() => {
  //   // 隐藏加载遮罩
  //   isLoading.value = false
  // })
}

const handleReset = () => {
  // 清空输入条件
  query.value.inputKeyword = ''
  query.value.inputDate = ''
  query.value.pageNum = 1
  currentPage.value = 1
  console.log('重置搜索条件')
  // 重新查询
  handleQuery()
}

// ==================== 场景切换 ====================

/** 下拉菜单展开状态 */
const dropdownOpen = ref<boolean>(false)

/**
 * 场景配置列表
 * 定义了三种主要场景：历史计划、决策思维链、动态筹划
 */
const scenes = [
  {
    value: 'history',
    label: '历史计划',
    icon: timeNoIcon,
    selectedIcon: timeSelectIcon
  },
  {
    value: 'decision',
    label: '决策思维链',
    icon: modelNoIcon,
    selectedIcon: modelSelectIcon
  },
  {
    value: 'dynamic',
    label: '动态筹划',
    icon: echartsNoIcon,
    selectedIcon: echartsSelectIcon
  }
]
/** 当前选中的场景 */
const currentScene = ref(scenes[0])

/** 切换下拉菜单的展开/收起状态 */
const toggleDropdown = () => {
  dropdownOpen.value = !dropdownOpen.value
}

/**
 * 选择场景并切换视图
 * 根据选择的场景类型，自动更新 viewMode 并处理相应的上下文数据清理或恢复
 * @param scene 选中的场景对象
 */
const selectScene = (scene: any) => {
  currentScene.value = scene
  dropdownOpen.value = false

  // 根据场景切换视图
  if (scene.value === 'history') {
    viewMode.value = 'list'
    selectedCardId.value = null // 清除选中状态
  } else if (scene.value === 'dynamic') {
    viewMode.value = 'streaming'
    // 切换到动态筹划时，尝试恢复SSE场景的卡片信息
    if (sseCardInfo.value) {
      selectedCardInfo.value = sseCardInfo.value
      console.log('[Machine] 切换到动态筹划，恢复SSE卡片信息:', selectedCardInfo.value)
    } else {
      // 如果没有SSE卡片信息，清空卡片信息（避免显示历史计划的卡片信息）
      selectedCardInfo.value = null
      console.log('[Machine] 切换到动态筹划，清空卡片信息')
    }
  } else if (scene.value === 'decision') {
    viewMode.value = 'decision'
    console.log('[Machine] 切换到决策思维链视图')
  }
}

// 查看详情
const viewDetail = (item: any) => {
  console.log('[Machine] 查看详情:', item.title, 'ID:', item.id)
  selectedCardId.value = item.id

  // 保存选中卡片的基本信息（历史记录场景）
  selectedCardInfo.value = {
    title: item.title,
    planName: item.planName,
    publishTime: item.publishTime,
    validPeriod: item.validPeriod,
    createTime: item.createTime
  }
  console.log('[Machine] 设置历史记录卡片信息:', selectedCardInfo.value)

  // 调用 API 获取详情数据
  // getHistoryCardById(item.id)
  //   .then((res: any) => {
  //     console.log('详情数据:', res)
  let res = {
    "screen2": [
      ["需求分析智能体", "方案设计智能体", "方案展示智能体", "思维导图智能体", "代码生成智能体", "输出优化智能体",],
      {
        "layout": "node",
        "需求分析智能体": [
          {
            "content": "**分析用户需求，理解要创建物理课程表**",
            "nodeName": "节点1"
          },
          {
            "content": "**确认需要提供多个方案让用户选择**",
            "nodeName": "节点2"
          }
        ]
      },
      {
        "layout": "text",
        "方案设计智能体": [
          {
            "content": "**准备力学、电磁学、热力学三个方案**",
            "nodeName": "节点1"
          },
        ]
      },
      {
        "layout": "text",
        "方案展示智能体": [
          {
            "content": "**分析用户需求，理解要创建物理课程表**",
          },
        ]
      },
      {
        "layout": "markmap",
        "思维导图智能体": [
          {
            "content": "# Example Task\n## Main 1\n### Sub 1\n#### Task 1\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### 装备物资方案展示内容\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n#### Task 2\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n### Sub 2\n#### Task 1\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n#### Task 2\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n## Main 1\n### Sub 1\n#### Task 1\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n#### Task 2\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n### Sub 2\n#### Task 1\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n#### Task 2\n##### pici 1\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}\n##### pici 2\n###### {pici:{mainTask: '海上巡逻',weaponMount: '光电吊舱',department: '第一航空大队',arrivalTime: '08:30',takeoffTime: '07:00',commShortWave: '频道A',subTask: '区域侦察',aircraftType: '运-8',fuelAmount: '12吨',flightSegment: '中空',minFuel: '2吨',coverageRule: '扇形搜索',target: '可疑船只',callsign: '猎鹰01',commandCode: 'CMD001',tailNumber: 'B-1234',landingTime: '10:15',commandUnit: '东部战区',taskType: '侦察任务',airfield: '东南机场',arrivalLocation: '目标海域',secondaryRadar: '开启',commUltraShort: '频道B'}}\n###### {hangxian:[{id: 1,name: '无人机Alpha',gridCoord: 'X12 Y34',altitude: 1500,speed: 85,arrivalTime: '09:52:15',fuelRemaining: 78}]}"
          },
        ]
      },
      {
        "layout": "gantt",
        "代码生成智能体": 
          {
            // 模拟推演环境参数
            simulation: {
              // 推演日期 (D日)
              currentDate: "2025-06-01",
              // 当前推演时间 (K时刻)
              currentTime: "2025-06-01 08:05:00",
            },
            // 原始任务数据列表 (树形结构)
            rawTasks: [
              {
                // 节点ID (唯一标识)
                id: "t1",
                // 节点名称
                name: "XXXXXX子任务类型-1",
                // 子节点列表 (有 children 视为分组节点)
                children: [
                  {
                    // 任务ID
                    id: "t1-1",
                    // 任务名称
                    name: "序号-1",
                    // 任务详细属性 (左侧列表悬浮显示)
                    detail: {
                      "机型": "1-2",
                      "挂载": "PL-1 x 41",
                      "部别": "xx部"
                    },
                    // 航线关键点列表 (扁平化，无 timeline 包裹)
                    waypoints: [
                      // time: 时间(YYYY-MM-DD HH:mm:ss), label: 航点标签, type: 类型(AIRPORT/ENTRY_POINT/EXIT_POINT/HOVER_POINT), location: 具体位置
                      { time: "2025-05-31 22:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" },
                      { time: "2025-06-01 07:15:00", label: "空域A", type: "HOVER_POINT", location: "空域A" },
                      { time: "2025-06-01 11:30:00", label: "XXX进入点", type: "ENTRY_POINT", location: "XXX进入点" },
                      { time: "2025-06-01 12:45:00", label: "空域B", type: "HOVER_POINT", location: "空域B" },
                      { time: "2025-06-01 14:00:00", label: "XXX退出点", type: "EXIT_POINT", location: "XXX退出点" },
                      { time: "2025-06-03 16:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" }
                    ]
                  },
                  {
                    id: "t1-2",
                    name: "序号-2",
                    detail: {
                      "机型": "y-1998",
                      "挂载": "PL-15 x 4",
                      "部别": "xx部"
                    },
                    waypoints: [
                      { time: "2025-06-01 09:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" },
                      { time: "2025-06-01 10:30:00", label: "空域D", type: "HOVER_POINT", location: "空域D" },
                      { time: "2025-06-01 11:30:00", label: "XXX进入点", type: "ENTRY_POINT", location: "XXX进入点" },
                      { time: "2025-06-01 14:00:00", label: "XXX退出点", type: "EXIT_POINT", location: "XXX退出点" },
                      { time: "2025-06-01 16:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" }
                    ]
                  }
                ]
              },
              {
                id: "t2",
                name: "XXXXXX子任务类型-2",
                children: [
                  {
                    id: "t2-1",
                    name: "序号-1",
                    detail: {
                      "机型": "y-1998",
                      "挂载": "PL-15 x 4",
                      "部别": "xx部"
                    },
                    waypoints: [
                      { time: "2025-06-01 09:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" },
                      { time: "2025-06-01 11:30:00", label: "XXX进入点", type: "ENTRY_POINT", location: "XXX进入点" },
                      { time: "2025-06-01 14:00:00", label: "XXX退出点", type: "EXIT_POINT", location: "XXX退出点" },
                      { time: "2025-06-01 16:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" }
                    ]
                  }
                ]
              },
              {
                id: "t3",
                name: "XXXXXX子任务类型-3",
                children: [
                  {
                    id: "t3-1",
                    name: "序号-1",
                    detail: {
                      "机型": "y-1998",
                      "挂载": "PL-15 x 4",
                      "部别": "xx部"
                    },
                    waypoints: [
                      { time: "2025-06-01 09:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" },
                      { time: "2025-06-01 11:30:00", label: "XXX进入点", type: "ENTRY_POINT", location: "XXX进入点" },
                      { time: "2025-06-01 12:45:00", label: "空域C", type: "HOVER_POINT", location: "空域C" },
                      { time: "2025-06-01 14:00:00", label: "XXX退出点", type: "EXIT_POINT", location: "XXX退出点" },
                      { time: "2025-06-01 16:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" }
                    ]
                  },
                  {
                    id: "t3-2",
                    name: "序号-2",
                    detail: {
                      "机型": "y-1998",
                      "挂载": "PL-15 x 4",
                      "部别": "xx部"
                    },
                    waypoints: [
                      { time: "2025-06-01 09:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" },
                      { time: "2025-06-01 11:30:00", label: "XXX进入点", type: "ENTRY_POINT", location: "XXX进入点" },
                      { time: "2025-06-01 14:00:00", label: "XXX退出点", type: "EXIT_POINT", location: "XXX退出点" },
                      { time: "2025-06-01 16:00:00", label: "XXX机场", type: "AIRPORT", location: "XXX机场" }
                    ]
                  }
                ]
              },
            ]
          }
        
      },
      {
        "layout": "summary",
        "输出优化智能体": [
          {
            "content": "# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n# 一级标题\n## 二级标题\n",
          }
        ]
        // "输出优化智能体": [
        //   {
        //     "content": "# 一级标题\n## 二级标题\n### 三级标题\n\n---\n\n**加粗**、*斜体*、~~删除线~~、`行内代码`。\n\n> 引用块\n> 第二行引用\n\n1. 有序列表项 A\n2. 有序列表项 B\n   - 嵌套无序列表 1\n   - 嵌套无序列表 2\n\n- [x] 已完成任务\n- [ ] 未完成任务\n\n```js\n// 代码块（高亮）\nfunction hello(name) {\n  console.log(`Hello, ${name}!`);\n}\n```\n\n| 表头1 | 表头2 |\n|-------|-------|\n| 单元格A1 | 单元格A2 |\n| 单元格B1 | 单元格B2 |\n\n[链接到 GitHub](https://github.com)",
        //   }
        // ]
      },
      { "tag": "isDone" }
    ]
  }
  selectedDetail.value = res
  viewMode.value = 'detail'
  //   })
  //   .catch((error: any) => {
  //     console.error('获取详情失败:', error)
  //   })
}

// 处理分页变化
const handlePageChange = (page: number) => {
  console.log('[Machine] 切换到第', page, '页')
  currentPage.value = page
  query.value.pageNum = page
}

/**
 * 处理完整的历史记录数据
 * 主要用于历史数据回显场景，非流式渲染
 * 1. 移除所有流式标记 (_streaming)
 * 2. 将所有节点标记为已完成 (completed: true)
 * @param data 完整的历史记录数据对象
 */
const processHistoryData = (data: any) => {
  console.log('[Machine] 历史数据场景 - 处理完整历史记录数据:', data)

  // 历史数据处理：移除 _streaming 标记，添加 completed 标记
  if (data && data.screen2 && Array.isArray(data.screen2)) {
    for (let i = 1; i < data.screen2.length; i++) {
      const item = data.screen2[i]

      // 跳过 isDone 标记
      if (item.tag === 'isDone') break

      // 移除流式标记（历史数据不应有流式标记）
      if (item._streaming) {
        delete item._streaming
      }

      // 获取智能体名称
      const agentNames = Object.keys(item).filter(key => key !== 'layout' && key !== 'tag')
      if (agentNames.length === 0) continue

      const agentName = agentNames[0]
      const messages = item[agentName]

      // 为每个节点添加 completed: true（历史数据都是完整的）
      if (Array.isArray(messages)) {
        messages.forEach((msg: any) => {
          msg.completed = true
        })
      }
    }
  }

  historyData.value = data
  console.log('[Machine] 历史数据加载完成，共', data.screen2?.length || 0, '项')
}

/**
 * 重置 Machine 窗口状态
 * 清空所有数据和状态，恢复到初始列表视图
 * 用于新建会话或重置操作
 */
const resetMachineState = () => {
  console.log('重置Machine窗口状态')
  // 清空历史数据
  historyData.value = null
  viewMode.value = 'list'
  selectedDetail.value = null
  selectedCardInfo.value = null
  sseCardInfo.value = null
  streamingMarkdown.value = ''
  isGanttLoading.value = false
  console.log('Machine窗口状态重置完成')
}

// ==================== 生命周期钩子 ====================

/**
 * 组件挂载后执行
 * 1. 初始化默认视图为列表模式
 * 2. 加载第一页数据
 * 3. 注册 Electron IPC 消息监听器，处理主窗口发送的消息
 */
onMounted(() => {
  // 默认显示历史记录列表视图
  viewMode.value = 'list'

  // 默认加载第一页数据
  handleQuery()

  // 监听来自主控制台的历史记录数据
  if (window.electronAPI && window.electronAPI.onDirectMessage) {
    window.electronAPI.onDirectMessage((_event: any, data: any) => {
      console.log('[Machine] 收到消息, type:', data.type)

      if (data.type === 'reset') {
        // 处理重置消息
        resetMachineState()
      } else if (data.type === 'history' && data.historyData) {
        // 历史记录加载：完整替换数据
        console.log('[Machine] 收到history消息，加载历史记录')
        processHistoryData(data.historyData)
      } else if (data.type === 'gantt_loading_start') {
        // Gantt智能体开始传输：显示加载遮罩
        console.log('[Machine] 收到gantt_loading_start消息，显示加载遮罩')
        isGanttLoading.value = true
      } else if (data.type === 'gantt_loading_complete') {
        // Gantt智能体数据传输完成：关闭加载遮罩
        console.log('[Machine] 收到gantt_loading_complete消息，关闭加载遮罩')
        isGanttLoading.value = false
      } else if (data.type === 'streaming_agent_content') {
        // SSE实时渲染：处理流式智能体内容（包括 markmap, text, gantt, summary等所有类型）
        console.log('[Machine] 收到streaming_agent_content:', data.layout, data.agentName, data.content.length, '字符')
        console.log('[Machine] 预览:', data.content.substring(0, 100).replace(/\n/g, ' | '))

        // 自动切换到动态筹划视图
        if (viewMode.value !== 'streaming') {
          viewMode.value = 'streaming'
          currentScene.value = scenes[2] // 动态筹划
          console.log('[Machine] 自动切换到动态筹划视图')
        }

        // 特殊处理：markmap类型需要同时更新streamingMarkdown（用于思维导图渲染）
        if (data.layout === 'markmap') {
          streamingMarkdown.value = data.content
          console.log('[Machine] 更新思维导图流式内容:', data.content.length, '字符')
        }

        // 初始化historyData
        if (!historyData.value) {
          historyData.value = { screen2: [] }
        }
        if (!historyData.value.screen2) {
          historyData.value.screen2 = []
        }

        // 查找该智能体的数据（通过智能体名称查找）
        const agentIndex = historyData.value.screen2.findIndex((item: any) => {
          if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
            // 获取智能体名称（排除 layout 和 tag）
            const keys = Object.keys(item).filter(k => k !== 'layout' && k !== 'tag' && k !== '_streaming')
            return keys.length > 0 && keys[0] === data.agentName
          }
          return false
        })

        if (agentIndex === -1) {
          // 智能体不存在，创建新的（只在流式渲染时创建）
          const agentData = {
            layout: data.layout,
            [data.agentName]: [{ content: data.content }],
            _streaming: true  // 标记为流式渲染中
          }
          historyData.value.screen2.push(agentData)
          console.log('[Machine] 创建新智能体(流式):', data.agentName, '索引:', historyData.value.screen2.length - 1)
        } else {
          // 智能体已存在，检查是否还在流式渲染状态
          const agentData = historyData.value.screen2[agentIndex]

          if (!agentData._streaming) {
            // 已被完整数据替换，忽略滞后的流式更新
            console.log('[Machine] 忽略滞后的流式更新(已有完整数据):', data.agentName)
            return
          }

          // 仍在流式渲染中，更新content
          if (agentData[data.agentName] && agentData[data.agentName][0]) {
            agentData[data.agentName][0].content = data.content
            console.log('[Machine] 更新智能体content(流式):', data.agentName, '长度:', data.content.length)
          }
        }

        // 强制触发响应式更新
        historyData.value = { ...historyData.value }
      } else if (data.type === 'streaming_content' && data.screen2) {
        // SSE实时渲染：处理完整的智能体数据（覆盖流式渲染的临时数据）
        console.log('[Machine] 收到streaming_content数据:', data.screen2)
        console.log('[Machine] 数据详情:', JSON.stringify(data.screen2).substring(0, 200))

        // 自动切换到动态筹划视图
        if (viewMode.value !== 'streaming') {
          viewMode.value = 'streaming'
          currentScene.value = scenes[2] // 动态筹划
          console.log('[Machine] 自动切换到动态筹划视图')
        }

        // 初始化historyData
        if (!historyData.value) {
          historyData.value = { screen2: [] }
        }
        if (!historyData.value.screen2) {
          historyData.value.screen2 = []
        }

        // 处理每个新数据项
        data.screen2.forEach((newItem: any) => {
          if (Array.isArray(newItem)) {
            // 智能体列表（第一条消息），直接添加
            historyData.value.screen2.push(newItem)
            console.log('[Machine] 添加智能体列表')
          } else if (typeof newItem === 'object' && newItem !== null) {
            // 检查是否是 cardInfo
            if (newItem.cardInfo) {
              // 提取卡片信息(SSE场景专用)
              if (!sseCardInfo.value) {
                sseCardInfo.value = {
                  title: newItem.cardInfo.title || '未命名计划',
                  planName: newItem.cardInfo.planName || '-',
                  publishTime: newItem.cardInfo.publishTime || '-',
                  validPeriod: newItem.cardInfo.validPeriod || '-',
                  createTime: newItem.cardInfo.createTime || '-'
                }
                console.log('[Machine] 设置SSE场景卡片信息:', sseCardInfo.value)
                // 如果当前在streaming模式，立即应用
                if (viewMode.value === 'streaming') {
                  selectedCardInfo.value = sseCardInfo.value
                }
              }
              // cardInfo 不需要添加到 screen2 数组中
              return
            }

            // 智能体数据对象
            const agentName = Object.keys(newItem).find(key => key !== 'layout' && key !== 'tag')

            if (!agentName) {
              // 没有智能体名称（可能是特殊标记），直接添加
              historyData.value.screen2.push(newItem)
              return
            }

            // 查找是否已有该智能体的流式渲染数据
            const existingIndex = historyData.value.screen2.findIndex((item: any) => {
              if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
                const keys = Object.keys(item).filter(k => k !== 'layout' && k !== 'tag' && k !== '_streaming')
                return keys.length > 0 && keys[0] === agentName
              }
              return false
            })

            if (existingIndex !== -1 && historyData.value.screen2[existingIndex]._streaming) {
              // 已存在流式渲染数据，用完整数据替换
              console.log('[Machine] 替换流式数据为完整数据:', agentName)
              historyData.value.screen2[existingIndex] = newItem

              // 如果是markmap类型,清空streamingMarkdown(流式渲染已完成)
              if (newItem.layout === 'markmap') {
                streamingMarkdown.value = ''
                console.log('[Machine] 清空思维导图流式内容(已有完整数据)')
              }
            } else if (existingIndex === -1) {
              // 不存在，添加新数据（可能是没有流式渲染的智能体）
              historyData.value.screen2.push(newItem)
              console.log('[Machine] 添加新智能体数据:', agentName)
            }
            // else: 已存在且不是流式数据，不处理（避免重复）
          }
        })

        console.log('[Machine] 当前screen2数据长度:', historyData.value.screen2.length)

        // 强制触发响应式更新
        historyData.value = { ...historyData.value }
      } else if (data.type === 'streaming_complete' && data.sessionData) {
        // SSE流式传输完成 - 不要替换现有数据，只做标记处理
        console.log('[Machine] 收到streaming_complete数据:', data.sessionData)
        console.log('[Machine] 当前historyData.screen2长度:', historyData.value?.screen2?.length || 0)

        // 清空流式 Markdown（因为完整数据已到）
        streamingMarkdown.value = ''

        // 重要：不调用 processHistoryData，因为它会替换掉所有已累积的流式数据
        // 如果需要标记完成状态，可以遍历现有数据添加 completed 标记
        if (historyData.value && historyData.value.screen2 && Array.isArray(historyData.value.screen2)) {
          for (let i = 1; i < historyData.value.screen2.length; i++) {
            const item = historyData.value.screen2[i]
            if (item.tag === 'isDone') break

            // 移除流式标记
            if (item._streaming) {
              delete item._streaming
            }

            // 获取智能体名称
            const agentNames = Object.keys(item).filter(key => key !== 'layout' && key !== 'tag')
            if (agentNames.length === 0) continue

            const agentName = agentNames[0]
            const messages = item[agentName]

            // 为每个节点添加 completed: true
            if (Array.isArray(messages)) {
              messages.forEach((msg: any) => {
                msg.completed = true
              })
            }
          }

          // 强制触发响应式更新
          historyData.value = { ...historyData.value }
          console.log('[Machine] SSE流式传输完成，数据已标记为完成')
        }
      } else {
        console.log('[Machine] 未处理的消息类型:', data.type, '数据:', data)
      }
    })
  }
})

// 组件卸载
onUnmounted(() => {
  // 清理工作（如有需要）
})
</script>

<style scoped>
/* 日期选择器组件内样式 - 需要使用 :deep() 穿透 */
.date-picker :deep(.el-date-editor) {
  width: 440px;
  height: 38px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(212, 255, 239, 0.6);
  border-radius: 4px;
  box-shadow: none;
}

.date-picker :deep(.el-input__wrapper) {
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 0;
}

.date-picker :deep(.el-input__inner) {
  color: #D4FFEF;
  font-size: 14px;
}

.date-picker :deep(.el-input__prefix),
.date-picker :deep(.el-input__suffix) {
  color: #D4FFEF;
  padding: 0 0 0 15px;
}

.date-picker :deep(.el-input__suffix) {
  display: none;
}

.date-picker :deep(.el-date-editor:hover),
.date-picker :deep(.el-date-editor.is-focus) {
  box-shadow: none;
  border-color: rgba(212, 255, 239, 0.6);
}

.date-picker :deep(.el-date-editor.is-focus .el-input__wrapper) {
  box-shadow: 0 0 0 1px transparent inset;
}

.date-picker :deep(.el-input__inner::placeholder) {
  color: #83a097;
}

/* 分页组件样式 - 需要使用 :deep() 穿透 */
.pagination-wrapper :deep(.el-pagination) {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.pagination-wrapper :deep(.el-pagination button) {
  background: transparent;
  color: #D4FFEF;
  border: none;
  border-radius: 4px;
  min-width: 32px;
  height: 32px;
  line-height: 32px;
  font-size: 14px;
}

.pagination-wrapper :deep(.el-pagination button:hover:not(:disabled)) {
  background: transparent;
  color: #06FFB0;
}

.pagination-wrapper :deep(.el-pagination button:disabled) {
  opacity: 0.4;
  cursor: not-allowed;
  color: #D4FFEF;
}

.pagination-wrapper :deep(.el-pager li) {
  background: transparent;
  color: #D4FFEF;
  border: none;
  border-radius: 4px;
  min-width: 32px;
  height: 32px;
  line-height: 32px;
  font-size: 14px;
}

.pagination-wrapper :deep(.el-pager li:hover) {
  background: transparent;
  color: #06FFB0;
}

.pagination-wrapper :deep(.el-pager li.is-active) {
  background: transparent;
  color: #06FFB0;
  font-weight: bold;
}

.pagination-wrapper :deep(.el-pagination__total) {
  color: #D4FFEF;
  font-size: 14px;
}

.pagination-wrapper :deep(.el-pagination__jump) {
  color: #D4FFEF;
  font-size: 14px;
}

.pagination-wrapper :deep(.el-pagination__jump .el-input__wrapper) {
  background: transparent;
  border: 1px solid #D4FFEF;
  border-radius: 4px;
  box-shadow: none;
}

.pagination-wrapper :deep(.el-pagination__jump .el-input__inner) {
  color: #D4FFEF;
  text-align: center;
}

.pagination-wrapper :deep(.el-pagination__jump .el-input__wrapper:hover) {
  border-color: #06FFB0;
}

.pagination-wrapper :deep(.el-pagination__jump .el-input__wrapper.is-focus) {
  border-color: #06FFB0;
  box-shadow: none;
}

.pagination-wrapper :deep(.el-pagination__editor.el-input) {
  width: 40px;
  height: 22px;
}

/* Loading 遮罩层样式 */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(2px);
  gap: 20px;
  z-index: 1000;
}

/* Loading GIF 样式 */
.loading-gif {
  width: 80px;
  height: 80px;
  object-fit: contain;
}

.loading-text {
  font-family: 'Source Han Sans', sans-serif;
  font-size: 16px;
  font-weight: 400;
  color: #D4FFEF;
  opacity: 0.8;
  animation: pulse 1.5s ease-in-out infinite;
  height: auto !important;
  margin: 0;
}

@keyframes pulse {

  0%,
  100% {
    opacity: 0.5;
  }

  50% {
    opacity: 1;
  }
}
</style>
